package com.yanqu.road.logic.xlogic.server;

import com.yanqu.road.entity.enums.eChannelType;
import com.yanqu.road.entity.servercenter.XServerName;
import com.yanqu.road.logic.bussiness.servercenter.XServerNameBussiness;
import com.yanqu.road.logic.xlogic.base.BaseXMap;
import com.yanqu.road.pb.cross3.server.CrossChannelServerProto;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class XServerNameMap extends BaseXMap {

    public XServerNameMap(String dbName, String tableName) {
        super(dbName, tableName);
    }

    /**
     * 渠道ID，区服ID，服务器名称
     */
    private final Map<Integer, Map<Long, XServerName>> serverNameMap = new ConcurrentHashMap<>();

    private final Object lock = new Object();

    /**
     * 添加区服名称
     */
    public void addServerName(int channelId, long serverId, String name) {
        synchronized (lock) {
            if (!serverNameMap.containsKey(channelId)) {
                serverNameMap.put(channelId, new ConcurrentHashMap<>());
            }
            Map<Long, XServerName> map = serverNameMap.get(channelId);
            if (!map.containsKey(serverId)) {
                XServerName xServerName = new XServerName(channelId, serverId, name);
                xServerName.setInsertOption();
                map.put(serverId, xServerName);
            } else {
                map.get(serverId).setName(name);
            }
        }
    }

    /**
     * 初始化数据
     */
    private void initServerName(List<XServerName> nameList) {
        for (XServerName serverName : nameList) {
            if (!serverNameMap.containsKey(serverName.getChannelId())) {
                serverNameMap.put(serverName.getChannelId(), new ConcurrentHashMap<>());
            }
            serverNameMap.get(serverName.getChannelId()).put(serverName.getServerId(), serverName);
        }
    }

    /**
     * 获取需要同步的数据
     */
    public CrossChannelServerProto.ServerNameListMsg.Builder getAllServerNameMsg() {
        CrossChannelServerProto.ServerNameListMsg.Builder builder = CrossChannelServerProto.ServerNameListMsg.newBuilder();
        for (Map<Long, XServerName> map : serverNameMap.values()) {
            for (XServerName xServerName : map.values()) {
                CrossChannelServerProto.ServerNameMsg.Builder tmpBuilder = CrossChannelServerProto.ServerNameMsg.newBuilder();
                tmpBuilder.setChannelId(xServerName.getChannelId());
                tmpBuilder.setServerId(xServerName.getServerId());
                tmpBuilder.setServerName(xServerName.getName());
                // 客户端要的地区号
                eChannelType channelType = eChannelType.forValue(xServerName.getChannelId());
                if (channelType != null) {
                    tmpBuilder.setPlaceFlag(channelType.getPlaceType().getValue());
                }
                builder.addNameList(tmpBuilder);
            }
        }
        return builder;
    }

    /**
     * 获取指定区服ID的名称
     *
     * @return 找不到就不会加到list里
     */
    public CrossChannelServerProto.ServerNameListMsg.Builder getServerNameMsg(List<Long> serverIdList) {
        CrossChannelServerProto.ServerNameListMsg.Builder builder = CrossChannelServerProto.ServerNameListMsg.newBuilder();
        for (long serverId : serverIdList) {
            for (Map<Long, XServerName> map : serverNameMap.values()) {
                if (map.containsKey(serverId)) {
                    XServerName xServerName = map.get(serverId);
                    CrossChannelServerProto.ServerNameMsg.Builder tmpBuilder = CrossChannelServerProto.ServerNameMsg.newBuilder();
                    tmpBuilder.setChannelId(xServerName.getChannelId());
                    tmpBuilder.setServerId(xServerName.getServerId());
                    tmpBuilder.setServerName(xServerName.getName());

                    // 客户端要的地区号
                    eChannelType channelType = eChannelType.forValue(xServerName.getChannelId());
                    if (channelType != null) {
                        tmpBuilder.setPlaceFlag(channelType.getPlaceType().getValue());
                    }

                    builder.addNameList(tmpBuilder);
                }
            }
        }
        return builder;
    }

    /**
     * 获取指定channel的名称
     */
    public CrossChannelServerProto.ServerNameListMsg.Builder getServerNameMsg(int channelId) {
        CrossChannelServerProto.ServerNameListMsg.Builder builder = CrossChannelServerProto.ServerNameListMsg.newBuilder();
        for (XServerName xServerName : serverNameMap.get(channelId).values()) {
            CrossChannelServerProto.ServerNameMsg.Builder tmpBuilder = CrossChannelServerProto.ServerNameMsg.newBuilder();
            tmpBuilder.setChannelId(xServerName.getChannelId());
            tmpBuilder.setServerId(xServerName.getServerId());
            tmpBuilder.setServerName(xServerName.getName());
            builder.addNameList(tmpBuilder);
        }
        return builder;
    }

    /**
     * 获取区服名称
     */
    public String getServerName(int channelId, long serverId) {
        Map<Long, XServerName> map = serverNameMap.get(channelId);
        if (map == null) {
            return "";
        }
        XServerName serverName = map.get(serverId);
        if (serverName == null) {
            return "";
        }
        return serverName.getName();
    }

    /**
     * 瓦舍临时用的获取渠道ID
     */
    public int getWasheChannelId(long serverId) {
        for (Map.Entry<Integer, Map<Long, XServerName>> entry : serverNameMap.entrySet()) {
            if (entry.getValue().containsKey(serverId)) {
                return entry.getKey();
            }
        }
        return 0;
    }

    @Override
    public void save() {
        for (Map<Long, XServerName> map : serverNameMap.values()) {
            for (XServerName xServerName : map.values()) {
                if (xServerName.isInsertOption()) {
                    XServerNameBussiness.addXServerName(dbName, tableName, xServerName);
                } else if (xServerName.isUpdateOption()) {
                    XServerNameBussiness.updateXServerName(dbName, tableName, xServerName);
                }
            }
        }
    }

    @Override
    public void loadDb(Object param) {
        List<XServerName> nameList = XServerNameBussiness.getXServerNameList(dbName, tableName);
        initServerName(nameList);
    }
}
